/*
 * Thread.cpp
 *
 *  Created on: Apr 6, 2011
 *      Author: alki
 */

#include "Thread.h"
#include <string.h>

int runthread(void *thread) {
	try {
		return ((Thread*)thread)->run();
	}
	catch(Exception *e) {
		e->out();
		delete e;
	}
	return 0;
}



Thread::Thread() {
	this->m_done=false;
	this->m_farbe=NULL;
	this->m_szene=NULL;
	this->m_thread=0;
	this->m_mutex=SDL_CreateMutex();

	this->m_thread=SDL_CreateThread(runthread,(void*)this);
	if(this->m_thread==NULL)
		throw new Exception(NULL,__FILE__,__LINE__,"Fataler Fehler bei SDL_CreateThread","");
}

Thread::~Thread() {
	this->m_done=true;
	this->m_farbe=NULL;
	this->m_szene=NULL;
	SDL_DestroyMutex(this->m_mutex);

	if(this->m_thread!=NULL)
		SDL_KillThread(this->m_thread);
}

bool Thread::finished() {
	SDL_mutexP(this->m_mutex);
	bool b=this->m_punkte.empty();
	SDL_mutexV(this->m_mutex);
	return b;
}

unsigned int Thread::GetSize() {
	SDL_mutexP(this->m_mutex);
	unsigned int n=this->m_punkte.size();
	SDL_mutexV(this->m_mutex);
	return n;
}

void Thread::Add(unsigned int x,unsigned int y) {
	if(this->m_szene==NULL)
		throw new Exception(NULL,__FILE__,__LINE__,"Fehler","Szene im Thread nicht gesetzt!");
	if(this->m_farbe==NULL)
		throw new Exception(NULL,__FILE__,__LINE__,"Fehler","Farbe im Thread nicht gesetzt!");

	PT p={x,y};
	SDL_mutexP(this->m_mutex);
	this->m_punkte.push_back(p);
	SDL_mutexV(this->m_mutex);
}

int Thread::run() {
	while(!this->m_done) {
		if(!this->finished()) {
			SDL_mutexP(this->m_mutex);
			PT p=this->m_punkte.front();
			this->m_punkte.pop_front();
			SDL_mutexV(this->m_mutex);
			this->m_farbe[p.x+p.y*this->m_szene->getWidth()]=this->m_szene->CalcRay(p.x,p.y);
		}
		else {
			usleep(1);
		}
	}
	return 0;
}
